home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / cpptask.exe / TSKDOS.ASM < prev    next >
Assembly Source File  |  1991-07-26  |  20KB  |  973 lines

  1. ;
  2. ;    CTask - DOS access module.
  3. ;
  4. ;    Public Domain Software written by
  5. ;        Thomas Wagner
  6. ;        Patschkauer Weg 31
  7. ;        D-1000 Berlin 33
  8. ;        West Germany
  9. ;
  10. ;
  11. ; The DOS interrupt (and the related direct disk I/O interrupts) are
  12. ; not reentrant. Access to DOS thus has to be channelled such that no
  13. ; two tasks use DOS services simultaneously. However, there is one
  14. ; exception to this rule. Whenever DOS is waiting for the keyboard, it
  15. ; issues a special interrupt, INT 28h, to signal that background
  16. ; processing for functions > 0Ch may be performed. This is used in the
  17. ; DOS interface for CTask in the following manner:
  18. ;
  19. ;   A task issuing a DOS interrupt will request one of two resources:
  20. ;   "lower_dos" for functions <= 0C, "upper_dos" for functions > 0C.
  21. ;   If a task gets access to "lower_dos", it will also request the
  22. ;   "upper_dos" resource to lock out other tasks from interrupting.
  23. ;   This "upper_dos" resource is shortly released on each INT 28, and
  24. ;   then immediately reclaimed, with task priority temporarily raised
  25. ;   to the maximum value. The first task waiting to execute a 
  26. ;   function > 0C will thus be scheduled to execute the request, but
  27. ;   the resource will be reassigned to the INT 28 handler as soon as
  28. ;   this request terminates, so the waiting task will not be delayed too
  29. ;   long.
  30. ;
  31. ; There are two additional safety measures which have to be taken to
  32. ; avoid getting into conflicts with other resident background programs,
  33. ; especially the DOS PRINT background spooler:
  34. ;
  35. ;   Before requesting any resource, the status of the DOS critical section
  36. ;   flag is checked. If this flag is set, the task is made waiting for
  37. ;   the flag to be cleared.
  38. ;   Only the task that set the flag will be allowed access to DOS.
  39. ;
  40. ;   Before actually executing the request, the status of the DOS in-use
  41. ;   flag is checked. If this flag is set, the task enters a busy waiting
  42. ;   loop, calling the scheduler so that the processor is not tied up.
  43. ;
  44. ; NOTE: The method for checking the status of DOS is described in-depth
  45. ;    in the book "The MS-DOS Encyclopedia" from Microsoft Press, in
  46. ;    the chapter on TSR programming. The logic in this module was
  47. ;    developed without the help of this book, so if you compare
  48. ;    the code here with the routines in the Encyclopedia, you may
  49. ;    notice that not all re-entry conditions are checked here.
  50. ;    According to my experience with debugging TSR's and CTask, the
  51. ;    logic should be sufficient for all but the most obscure TSR's.
  52. ;    If you want to be completely on the safe side, you might consider
  53. ;    adding the more thorough checks listed in the Encyclopedia.
  54. ;
  55. ;
  56.     name    tskdos
  57. ;
  58.     .model    large
  59. ;
  60.     public    _tsk_install_dos
  61.     public    _tsk_remove_dos
  62. ;
  63. ;
  64.     include    tsk.mac
  65. ;
  66. CSECT        =    2ah    ; Critical Section Interrupt
  67. get_in_use_flag    =    34h    ; DOS-function to get in_use_flag address
  68. ;
  69. ;
  70. intseg    segment at 0
  71.         org    20h*4
  72. termoff        dw    ?    ; program terminate vector
  73. termseg        dw    ?
  74.         org    21h*4
  75. idosoff        dw    ?    ; dos interrupt
  76. idosseg        dw    ?
  77.         org    25h*4
  78. absreadoff    dw    ?    ; absolute disk read
  79. absreadseg    dw    ?
  80.         org    26h*4
  81. abswriteoff    dw    ?    ; absolute disk write
  82. abswriteseg    dw    ?
  83.         org    27h*4
  84. keepoff        dw    ?    ; Terminate but stay resident
  85. keepseg        dw    ?
  86.         org    28h*4
  87. idleoff        dw    ?    ; dos idle interrupt
  88. idleseg        dw    ?
  89.         org    CSECT*4
  90. csectoff    dw    ?    ; dos critical section
  91. csectseg    dw    ?
  92. ;
  93. intseg    ends
  94. ;
  95. ;----------------------------------------------------------------------------
  96. ;
  97. ;       externally defined variables
  98. ;
  99.         extrn   _tsk_current: dword
  100.         extrn   _lower_dos: resource
  101.         extrn   _upper_dos: resource
  102.         extrn   _critical: flag
  103. ;
  104. ;       externally defined functions
  105. ;
  106.         extrn   _asm_request_resource: far
  107.         extrn   _asm_release_resource: far
  108.         extrn   _asm_set_flag: far
  109.         extrn   _asm_clear_flag: far
  110.         extrn   _asm_wait_flag_clear: far
  111.         extrn   _asm_remove_tasker: far
  112.         extrn   scheduler: far
  113. ;
  114.     .data
  115. ;
  116. ;
  117. term_err_msg    db    0dh,0ah,"Program terminated - CTask uninstalled"
  118.         db    0dh,0ah,'$'
  119. ;
  120. idle_active    db    0            ; Idle-Interrupt active
  121. dos310        db    0        ; DOS version >= 3.10
  122. ;
  123. ;
  124.     .data?
  125. ;
  126. in_use        dd    ?        ; Adress of DOS in-use-flag
  127. in_error    dd    ?        ; Adress of DOS error-mode-flag
  128. ;
  129. ;
  130. idle_ss        dw    ?        ; Stack save
  131. idle_sp        dw    ?
  132. ;
  133.         dw    256 dup(?)    ; Stack for IDLE-Interrupt
  134. local_stack    label    word
  135. ;
  136.     .code
  137. ;
  138. ;    Original Interrupt-Entries
  139. ;
  140. savtermoff    dw    ?        ; Terminate vector save
  141. savtermseg    dw    ?
  142. ;
  143. savdos        label    dword        ; original DOS-Entry
  144. savdosoff    dw    ?
  145. savdosseg    dw    ?
  146. ;
  147. savidle        label    dword        ; original IDLE-Entry
  148. savidleoff    dw    ?
  149. savidleseg    dw    ?
  150. ;
  151. savcsect    label    dword        ; Critical Section save
  152. savcsectoff    dw    ?
  153. savcsectseg    dw    ?
  154. ;
  155. savabsread    label    dword        ; Absolute Disk Read save
  156. savabsreadoff    dw    ?
  157. savabsreadseg    dw    ?
  158. ;
  159. savabswrite    label    dword        ; Absolute Disk Write save
  160. savabswriteoff    dw    ?
  161. savabswriteseg    dw    ?
  162. ;
  163. savkeepoff    dw    ?        ; Terminate resident vector save
  164. savkeepseg    dw    ?
  165. ;
  166. critsect_active    db    0        ; DOS Critical Section active
  167. ctask_active    db    0        ; CTask DOS call active
  168. crit_task    dd    ?        ; Task requesting critical section
  169. ;
  170. ;
  171. dos    macro
  172.     pushf
  173.     cli
  174.     call    cs:savdos
  175.     endm
  176. ;
  177. ;---------------------------------------------------------------------------
  178. ;
  179.     .code
  180. ;
  181. ;
  182. ;    void tsk_install_dos (void)
  183. ;
  184. ;        Install DOS handler
  185. ;
  186. ;       Invoked by tasker_class::tasker_class
  187. ;
  188. _tsk_install_dos    proc
  189. ;
  190. ;
  191. ;    Get the address of DOS's in_use-flag. This flag indicates that
  192. ;    DOS is already active. This might happen if there are other
  193. ;    background tasks, like popups or print spoolers, active in
  194. ;    parallel to CTask.
  195. ;    This is also the address of the critical error flag in DOS. Beginning 
  196. ;    with DOS 3.10 the flag is located one byte before the in_use_flag.
  197. ;    With older DOS versions, we would have to search through DOS for the 
  198. ;    address. This is omitted here, but you could include the code
  199. ;    for pre 3.1 versions from pages 378-379 of the MS-DOS Encyclopedia.
  200. ;    
  201.     mov    ah,get_in_use_flag
  202.     int    21h
  203.     mov    word ptr in_use,bx
  204.     mov    word ptr in_use+2,es
  205.     mov    word ptr in_error+2,es
  206. ;
  207.     push    bx
  208.     mov    ah,30h
  209.     int    21h
  210.     pop    bx
  211.     cmp    al,3
  212.     jb    not_dos3
  213.     cmp    al,0ah
  214.     je    not_dos3    ; OS/2 compatibility box
  215.     cmp    ah,10
  216.     jb    not_dos3
  217.     inc    dos310
  218.     dec    bx
  219.     mov    word ptr in_error,bx
  220.     jmp    short save_ints
  221. ;
  222. not_dos3:
  223.  
  224. ;
  225. ;    Save old interrupt vectors
  226. ;
  227. save_ints:
  228.         push    es
  229.     xor    ax,ax
  230.     mov    es,ax
  231. ;
  232.         assume  es:intseg
  233. ;
  234.     mov    ax,termoff        ; DOS
  235.     mov    savtermoff,ax
  236.     mov    ax,termseg
  237.     mov    savtermseg,ax
  238. ;
  239.     mov    ax,idosoff        ; DOS
  240.     mov    savdosoff,ax
  241.     mov    ax,idosseg
  242.     mov    savdosseg,ax
  243. ;
  244.     mov    ax,idleoff        ; IDLE
  245.     mov    savidleoff,ax
  246.     mov    ax,idleseg
  247.     mov    savidleseg,ax
  248. ;
  249.     mov    ax,csectoff        ; Critical Section
  250.     mov    savcsectoff,ax
  251.     mov    ax,csectseg
  252.     mov    savcsectseg,ax
  253. ;
  254.     mov    ax,absreadoff        ; Absolute Disk read
  255.     mov    savabsreadoff,ax
  256.     mov    ax,absreadseg
  257.     mov    savabsreadseg,ax
  258. ;
  259.     mov    ax,abswriteoff        ; Absolute Disk write
  260.     mov    savabswriteoff,ax
  261.     mov    ax,abswriteseg
  262.     mov    savabswriteseg,ax
  263. ;
  264.     mov    ax,keepoff        ; Terminate Resident
  265.     mov    savkeepoff,ax
  266.     mov    ax,keepseg
  267.     mov    savkeepseg,ax
  268. ;
  269. ;    Enter new Interrupt-Entries
  270. ;
  271.     cli
  272.     mov    idosoff,offset dosentry        ; DOS-Entry
  273.     mov    idosseg,cs
  274.     mov    idleoff,offset idleentry    ; Idle-Entry
  275.     mov    idleseg,cs
  276.     mov    termoff,offset terminate_int    ; Terminate Process Entry
  277.     mov    termseg,cs
  278.     mov    csectoff,offset critsectint    ; Critical Section Entry
  279.     mov    csectseg,cs
  280.     mov    keepoff,offset keep_int        ; Keep Process Entry
  281.     mov    keepseg,cs
  282.     mov    absreadoff,offset absread_int    ; Absolute Disk Read Entry
  283.     mov    absreadseg,cs
  284.     mov    abswriteoff,offset abswrite_int    ; Absolute Disk Write Entry
  285.     mov    abswriteseg,cs
  286.     sti
  287.         pop     es
  288. ;
  289.     ret
  290. ;
  291.     assume    es:nothing
  292. ;
  293. _tsk_install_dos    endp
  294. ;
  295. ;
  296. ;    void tsk_remove_dos (void)
  297. ;
  298. ;       Un-install DOS handler
  299. ;
  300. _tsk_remove_dos    proc
  301. ;
  302. ;    Delete resources & flags
  303. ;
  304.         push    es
  305.     xor    ax,ax
  306.     mov    es,ax
  307. ;
  308.         assume  es:intseg
  309. ;
  310. ;    Restore interrupt entries
  311. ;
  312.     cli
  313.     mov    ax,savtermoff
  314.     mov    termoff,ax
  315.     mov    ax,savtermseg
  316.     mov    termseg,ax
  317. ;
  318.     mov    ax,savdosoff
  319.     mov    idosoff